package com.zhengming.juc;

//  https://blog.csdn.net/mofeizhi/article/details/106816026
//volatile缓存行共享问题
public class T02_02CacheLinePadding {
    // 一个缓存行中的任意一个数据更改，cpu都会从缓存中重新读取一行中的所有其他数据
    private static class Padding {
        // 缓存行大小为64字节
        // 缓存行初始化56字节
        public volatile long p1, p2, p3, p4, p5, p6, p7;
    }

    private static class T extends Padding {
        public volatile long x = 0L;
    }

    public static T[] arr = new T[2];

    static {
        /**
         *  假设两个在一个缓存行
         *    1.如果这两个元素加起来不满64字节，他们就会在同一个缓存行之中
         *    2.两个线程操作这两个不同的元素时，因为两个能共存在一个缓存行
         *    3.此时修改其中一个元素的x值都能使其他或者当前线程再去缓存中重新提取两个共存的缓存行
         * 此时即将操作的两个数组元素此时都是56+8 64字节，
         * 两个线程操作这两个元素都在各自的缓存行之中，不会因为另一个元素的改变再去缓存中重新读取一遍
         */
        arr[0] = new T();
        arr[1] = new T();
    }

    public static void main(String[] args) {

        Thread t1 = new Thread(() -> {
            for (long i = 0; i < 1000_0000L; i++) {
                arr[0].x = i;
            }
        });

        Thread t2 = new Thread(() -> {
            for (long i = 0; i < 1000_0000L; i++) {
                arr[1].x = i;
            }
        });

        long start = System.nanoTime();
        try {
            t1.start();
            t2.start();
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        long end = System.nanoTime();
        System.out.println((end - start) / 100_0000L);
    }

}
